import re
import time
import uuid
import json

import allure

from conf.setting import replace_info
from tools.handle_faker import HandleFaker
from tools.handle_global_data import HandleGlobalData
from tools.handle_mysql import mysql
from tools.handle_logs import mylog



class HandleReplace:
    """
    1、做参数替换
    2、数据格式转换

    """
    def __init__(self):
        self.handle_faker = HandleFaker()


    #读取setting.py的账号数据并设置为全局属性
    def __get_setting_set_attribute(self,user_info:dict):
        if len(list(user_info.keys())) > 0 :
            for key,value in user_info.items():
                setattr(HandleGlobalData, key, str(value))
        else:
            print("无需从配置文件读取数据设置为属性")


    #前置sql语句
    @allure.step("执行前置sql语句")
    def setup_sql(self,sql_list:str):
        try:
            mylog.info(msg=f"setup_sql入参数据类型: {type(sql_list)}")
            mylog.info(msg=f"setup_sql入参：{sql_list}")
            if sql_list:
                mylog.info(msg="sql_list不为空，需要执行前置sql语句")
                sql_list = sql_list if isinstance(sql_list,list) else json.loads(sql_list)
                for sql in sql_list:
                    #替换sql语句的数据
                    new_sql = self.replace_sql(sql=sql)
                    #查询数据库获取sql语句要查询的数据,返回dict，拿到key作为全局变量的key，value作为值设置为全局变量
                    # {"mobile_code":"221190"}
                    result_dict_list = mysql.get_data_dict(sql=new_sql)
                    mylog.info(f"sql结果类型：{type(result_dict_list)}")
                    if len(result_dict_list) >0 :
                        #遍历sql查询结果，结果是dict集
                        for dict_data in result_dict_list:
                            mylog.info(f"sql结果类型：{type(dict_data)}")
                            #遍历字典，设置为类属性
                            for key ,value in dict_data.items():
                                setattr(HandleGlobalData, key, str(value))
                    else:
                        mylog.info(msg="前置sql语句查询到的数据为空，不用设置属性")
            else:
                mylog.info(msg="excel中setup_sql字段为空")
        except Exception as e:
            mylog.exception(msg=e)
            raise TypeError


    #获取需要替换的数据，然后设置为类属性(全局变量)
    def get_data_setattribute(self,key):
        #从配置文件读取账号设置为类属性，手机号？？？,秒杀订单的user
        self.__get_setting_set_attribute(user_info=replace_info)
        if key == "time":
            t = str(int(time.time() * 1000))
            #设置全局变量的值
            setattr(HandleGlobalData,key,t)
        elif key == "sessionUUID":
            session_uuid = str(uuid.uuid4())
            setattr(HandleGlobalData, key, session_uuid)
        elif key == "partyCode":
            #不存在就设置一个，存在就不去更新
            if not hasattr(HandleGlobalData,key):
                print("partyCode不存在，设置partyCode的值")
                setattr(HandleGlobalData, key, str(int(time.time() * 1000)))
            else:
                print("partyCode已存在，不用覆盖partyCode的值")
        elif key == "mobile":
            #要生成一个手机号，这个手机号不能被注册过
            #将未注册的手机号，设置为全局变量
            if not hasattr(HandleGlobalData, key):
                phone = self.handle_faker.get_phone()
                setattr(HandleGlobalData, key, phone)
            else:
                print("mobile已存在，不用覆盖mobile的值")
        else:
            print("已经在全局变量中或者未实现特殊处理")

    #sql语句的参数替换 ["file_path"]
    def replace_sql(self,sql:str):
        try:
            #获取需要替换的key
            key_list = re.findall("#(\w.+?)#", sql)
            if len(key_list) > 0 :
                for key in key_list:
                    #sql中需要替换数据,需要替换的数据从哪里来的
                    self.get_data_setattribute(key=key)
                #获取数据再替换数据
                # 统一替换数据
                for key in key_list:
                    if hasattr(HandleGlobalData, key):
                        sql = sql.replace(f"#{key}#", getattr(HandleGlobalData, key))
                    else:
                        mylog.info(msg="类属性不存在，无法替换数据")
                #返回替换后的sql语句
            else:
                mylog.info(msg="sql中不需要替换数据")
            mylog.info(msg=f"return 数据{sql}")
            return sql
        except Exception as e:
            mylog.exception(msg=e)
            raise TypeError

    @allure.step("替换请求数据")
    #请求参数的数据替换
    def replace_data(self,data:str):
        """
        做参数替换
        1、需要替换谁
        2、拿什么替换，从哪里来的
        3、如何替换replace

        :param data:
        :return:
        """
        if data:
            # {"mobile":"#mobile#"}
            # key_list = ['time', 'sessionUUID']
            key_list = re.findall("#(\w.+?)#",data)
            print("正则获取需要替换的数据：",key_list)
            if len(key_list)>0:
                for key in key_list:
                    #获取需要替换的数据，设置为属性(全局变量)
                    self.get_data_setattribute(key=key)

                    # 获取需要替换的数据，设置为属性(全局变量)
                    # if key == "time":
                    #     t = str(int(time.time() * 1000))
                    #     data = data.replace(f"#{key}#",t)
                    # elif key == "sessionUUID":
                    #     session_uuid = str(uuid.uuid4())
                    #     data = data.replace(f"#{key}#", session_uuid)

                #统一替换数据
                for key in key_list:
                    if hasattr(HandleGlobalData,key):
                        data = data.replace(f"#{key}#",getattr(HandleGlobalData,key))
                    else:
                        print("类属性不存在，无法替换数据")

                #将jsonstr转换成python对象
                data = json.loads(data)
                print('参数替换后：：',type(data),data)
                return data
            else:
                #将jsonstr转换成python对象
                data = json.loads(data)
                return data
        else:
            print("data参数为空不需要参数替换")
            return {}



